home *** CD-ROM | disk | FTP | other *** search
Text File | 2007-10-12 | 46.1 KB | 1,513 lines |
- // vim: ts=2 sw=2 expandtab cindent
- //
- // BEGIN FLOCK GPL
- //
- // Copyright Flock Inc. 2005-2007
- // http://flock.com
- //
- // This file may be used under the terms of of the
- // GNU General Public License Version 2 or later (the "GPL"),
- // http://www.gnu.org/licenses/gpl.html
- //
- // Software distributed under the License is distributed on an "AS IS" basis,
- // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- // for the specific language governing rights and limitations under the
- // License.
- //
- // END FLOCK GPL
- //
-
- // Developer ID = 1aiV9CsTs3o
- // Developer Secret = flock_is_open_source
-
- const ENABLE_DEBUG = true; // switch to turn off slow debug code for production
- function DEBUG(x) { if (ENABLE_DEBUG) debug("flockYouTubeService: "+x+"\n"); }
-
- const Cc = Components.classes;
- const Ci = Components.interfaces;
- const Cr = Components.results;
- const Cu = Components.utils;
-
- const YT_DEVID = "1aiV9CsTs3o";
- const YT_DEVSECRET = "flock_is_open_source";
- const YOUTUBE_CID = Components.ID('{DCB6A01E-7D4A-4C30-AB3D-9CC98C02F617}');
- const YOUTUBE_CONTRACTID = '@flock.com/?photo-api-youtube;1';
- const YOUTUBE_FAVICON = "http://www.youtube.com/favicon.ico";
- const YOUTUBE_TITLE = "YouTube Web Service";
- const SERVICE_ENABLED_PREF = "flock.service.youtube.enabled";
- const CATEGORY_COMPONENT_NAME = "YouTube JS Component"
- const CATEGORY_ENTRY_NAME = "youtube"
-
- const FLOCK_PHOTO_CONTRACTID = '@flock.com/photo;1';
- const FLOCK_PHOTOPERSON_CONTRACTID = '@flock.com/photo-person;1';
- const FLOCK_PHOTO_ALBUM_CONTRACTID = '@flock.com/photo-album;1';
- const PHOTOAPIMGR_CONTRACTID = "@flock.com/photo-api-manager;1?";
-
- const OBS_TOPIC_XPCOMSHUTDOWN = "xpcom-shutdown";
-
- var gCompTK;
- function getCompTK() {
- if (!gCompTK) {
- gCompTK = Cc["@flock.com/singleton;1"]
- .getService(Ci.flockISingleton)
- .getSingleton("chrome://browser/content/flock/services/common/load-compTK.js")
- .wrappedJSObject;
- }
- return gCompTK;
- }
-
- loadLibraryFromSpec("chrome://browser/content/flock/photo/photoAPI.js");
-
- var gTimers = []; // For use with the scheduler
-
- // String defaults... may be updated later through Web Detective
- var gStrings = {
- "domains": "youtube.com",
- "userlogin": "http://www.youtube.com/",
- "userprofile": "http://www.youtube.com/profile?user=%accountid%",
- "editprofile": "http://youtube.com/my_profile",
- "inbox": "http://youtube.com/my_messages",
- "subscriptions": "http://youtube.com/subscription_center"
- };
-
- /* JMC - Notes for refactoring
-
- CTOR - Always addsObserver for flock-data-ready,
- so that the service can be initialized with a proper faves-coop.
-
- Updating actions at CTOR time is expensive
- - do in polling instead?
- - or on state change
-
- */
-
-
- function youtubeVideo() {
- }
-
- youtubeVideo.prototype= {
- id: "",
- thumbnail: "",
- webPageUrl: "",
- midSizePhoto: "",
- largeSizePhoto: "",
- title: "",
- username: "",
- userid: "",
- is_public: "true",
- is_video: "true",
- has_miniView: "true",
- svcShortName: 'youtube',
- buildTooltip: function( ) {
- // do we have to use document from the window to ceate elements? -- ja
- var wm = Cc["@mozilla.org/appshell/window-mediator;1"]
- .getService(Ci.nsIWindowMediator);
- var win = wm.getMostRecentWindow('navigator:browser');
- if (!win) return null;
-
- var box = win.document.createElement('vbox');
- box.setAttribute('style', 'max-width: 250px');
-
- var title = win.document.createElement('label');
- title.setAttribute('value', this.title );
- title.setAttribute('crop', 'end');
- box.appendChild(title);
-
- if( this.length_seconds)
- {
- var lbl = win.document.createElement('label');
- lbl.setAttribute('value', 'Length: ' + this.length_seconds + ' seconds');
- box.appendChild(lbl);
- }
- if(this.rating_avg)
- {
- var lbl = win.document.createElement('label');
- lbl.setAttribute('value', 'Rating: ' + this.rating_avg + ' (' + this.rating_count + ' times)');
- box.appendChild(lbl);
- }
- if(this.view_count)
- {
- var lbl = win.document.createElement('label');
- lbl.setAttribute('value', 'Views: ' + this.view_count );
- box.appendChild(lbl);
- }
-
- if(!(this.length_seconds && this.rating_avg && this.view_count))
- {
- //if the tooltip does not these metadata -- show the author
- var lbl = win.document.createElement('label');
- lbl.setAttribute('value', this.username );
- lbl.setAttribute('class', 'user');
- box.appendChild(lbl);
- }
-
- var vbox = win.document.createElement('vbox');
- var cbox = win.document.createElement('cbox');
- var largeImg = win.document.createElement('image');
- largeImg.setAttribute('src', this.midSizePhoto);
- largeImg.setAttribute('style', 'margin-bottom: 2px;');
- var spacer = win.document.createElement('spacer');
- spacer.setAttribute('flex', '1');
- cbox.appendChild(largeImg);
- cbox.appendChild(spacer);
- vbox.appendChild(cbox);
- vbox.appendChild(box);
-
- return vbox;
- },
- buildHTML: function ( ) {
- var flashUrl = this.webPageUrl.replace(/\/\?v\=/,'/v/');
-
- return '<object width="425" height="350">'
- + '<param name="movie" value="'+flashUrl+'"/>'
- + '<embed src="'+flashUrl+'" type="application/x-shockwave-flash" width="425" height="350"/></object>';
- },
- buildBBCode: function ( ) {
- var video = this.webPageUrl.replace(/\/\?v\=/,'/watch?v=');
- return '[youtube]' + video + '[/youtube]'
- },
- buildMiniPage: function ( ) {
- var theurl = this.webPageUrl.replace(/\/\?v\=/,'/v/');
- return '<html><head><title>' + this.title + ' (' + this.username + ')</title></head>' +
- '<body><object width="425" height="350">' +
- '<param name="movie" value="'+theurl+'"/>' +
- '<center><embed src="'+theurl+'&autoplay=1" type="application/x-shockwave-flash" width="425" height="350"/></object></center></body></html>';
- },
-
- QueryInterface: function(iid) {
- if (!iid.equals(Ci.nsISupports) &&
- !iid.equals(Ci.flockIPhoto)) {
- throw Components.results.NS_ERROR_NO_INTERFACE;
- }
- return this;
- }
- };
-
- youtubeVideo.prototype.__defineGetter__('metaData', function () {
- var metaData = Cc["@mozilla.org/hash-property-bag;1"].createInstance(Ci.nsIWritablePropertyBag2);
- metaData.setPropertyAsAString("title", this.title);
- metaData.setPropertyAsAString("length", this.length_seconds);
- metaData.setPropertyAsAString("views", this.view_count);
- metaData.setPropertyAsAString("rating", this.rating_avg);
-
- metaData.QueryInterface(Ci.nsIPropertyBag);
-
- return metaData;
- })
-
-
- // ================================================
- // ========== BEGIN youtubeService class ==========
- // ================================================
-
- function youtubeService()
- {
- this.obs = Components.classes["@mozilla.org/observer-service;1"]
- .getService(Components.interfaces.nsIObserverService);
- this.obs.addObserver(this, OBS_TOPIC_XPCOMSHUTDOWN, false);
- this.acUtils = Components.classes["@flock.com/account-utils;1"]
- .getService(Components.interfaces.flockIAccountUtils);
- this.status = Components.interfaces.flockIWebService.STATUS_UNKNOWN;
- this.url = "http://www.youtube.com";
- this.mIsInitialized = false;
- this._ctk = {
- interfaces: [
- "nsISupports",
- "nsISupportsCString",
- "nsIClassInfo",
- "nsIObserver",
- "flockIWebService",
- "flockIMediaWebService",
- "flockISocialWebService",
- "flockIManageableWebService",
- "flockIPhotoAPI",
- "flockIPollingService",
- //"flockIPeopleActionController",
- ],
- shortName: "youtube",
- fullName: "YouTube",
- description: YOUTUBE_TITLE,
- favicon: YOUTUBE_FAVICON,
- CID: YOUTUBE_CID,
- contractID: YOUTUBE_CONTRACTID,
- accountClass: youtubeAccount,
- needPassword: false
- };
- this._logger = Cc['@flock.com/logger;1'].createInstance(Ci.flockILogger);
- this._logger.init('youtube');
- this._profiler = Cc["@flock.com/profiler;1"].getService(Ci.flockIProfiler);
- this.init();
- }
-
-
- // BEGIN nsIObserver interface
- youtubeService.prototype.observe =
- function youtubeService_observe(subject, topic, state)
- {
- switch (topic) {
- case OBS_TOPIC_XPCOMSHUTDOWN:
- {
- this.obs.removeObserver(this, OBS_TOPIC_XPCOMSHUTDOWN);
- }; break;
- }
- }
- // END nsIObserver interface
-
-
- youtubeService.prototype.init =
- function youtubeService_init()
- {
- DEBUG(".init()");
-
- // Prevent re-entry
- if (this.mIsInitialized) return;
- this.mIsInitialized = true;
-
- var evtID = this._profiler.profileEventStart("youtube-init");
-
- this.prefService = Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefBranch);
- if ( this.prefService.getPrefType(SERVICE_ENABLED_PREF) &&
- !this.prefService.getBoolPref(SERVICE_ENABLED_PREF) )
- {
- DEBUG("Pref "+SERVICE_ENABLED_PREF+" set to FALSE... not initializing.");
- var catMgr = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
- catMgr.deleteCategoryEntry("wsm-startup", CATEGORY_COMPONENT_NAME, true);
- catMgr.deleteCategoryEntry("flockIPhotoAPI", CATEGORY_ENTRY_NAME, true);
- catMgr.deleteCategoryEntry("flockWebService", CATEGORY_ENTRY_NAME, true);
- return;
- }
-
- this.faves_coop = Components.classes['@flock.com/singleton;1']
- .getService(Components.interfaces.flockISingleton)
- .getSingleton('chrome://browser/content/flock/common/load-faves-coop.js')
- .wrappedJSObject;
- this.account_root = this.faves_coop.accounts_root;
- this.ytPersonRoot = new this.faves_coop.Folder("urn:youtube:peopleroot", {name: "YouTube People"});
-
- this.ytService = new this.faves_coop.Service(
- "urn:youtube:service",
- {
- name: "youtube",
- desc: "The YouTube Service",
- loginURL: gStrings["userlogin"],
- contactLabel: 'Contacts'
- }
- );
- this.ytService.serviceId = YOUTUBE_CONTRACTID;
- var ytHomepage = new this.faves_coop.Favorite(
- "urn:flock:youtube:actions:homepage", {
- name: "youtube.com",
- URL: "http://www.youtube.com"
- });
-
- var ytOpenProfile = new this.faves_coop.Action(
- "urn:flock:youtube:actions:openprofile", {
- name: "Open Profile",
- method: "openProfile",
- service: YOUTUBE_CONTRACTID,
- flavour: "view"
- });
-
- var ytMySubs = new this.faves_coop.Action(
- "urn:flock:youtube:actions:mysubscriptions", {
- name: "Open Subscriptions",
- method: "openSubscriptions",
- service: YOUTUBE_CONTRACTID,
- flavour: "accountview"
- });
-
- var ytMyInbox = new this.faves_coop.Action(
- "urn:flock:youtube:actions:myinbox", {
- name: "Open Inbox",
- method: "openInbox",
- service: YOUTUBE_CONTRACTID,
- flavour: "accountview"
- });
-
- var ytMyVideos = new this.faves_coop.Action(
- "urn:flock:youtube:actions:myvideos", {
- name: "Open Videos",
- method: "openVideos",
- service: YOUTUBE_CONTRACTID,
- flavour: "view"
- });
-
- var ytMyFavoriteVideos = new this.faves_coop.Action(
- "urn:flock:youtube:actions:myfavvideos", {
- name: "Open Favorite Videos",
- method: "openFavVideos",
- service: YOUTUBE_CONTRACTID,
- flavour: "view",
- isPrimary: true
- });
-
- var ytPostComment = new this.faves_coop.Action(
- "urn:flock:youtube:actions:postcomment", {
- name: "Post Comment",
- method: "postComment",
- service: YOUTUBE_CONTRACTID,
- flavour: "contact"
- });
-
- var ytEditProfile = new this.faves_coop.Action(
- "urn:flock:youtube:actions:editprofile", {
- name: "Edit Profile",
- method: "editProfile",
- service: YOUTUBE_CONTRACTID,
- flavour: "accountaction"
- });
-
- var ytViewFriends = new this.faves_coop.Action(
- "urn:flock:youtube:actions:viewFriends", {
- name: "View Contacts",
- method: "viewFriends",
- service: YOUTUBE_CONTRACTID,
- flavour: 'view'
- });
-
- this.ytService.children.addOnce(ytViewFriends);
- this.ytService.children.addOnce(ytHomepage);
- this.ytService.children.addOnce(ytOpenProfile);
- this.ytService.children.addOnce(ytMySubs);
- this.ytService.children.addOnce(ytMyInbox);
- this.ytService.children.addOnce(ytMyVideos);
- this.ytService.children.addOnce(ytMyFavoriteVideos);
- this.ytService.children.addOnce(ytPostComment);
- this.ytService.children.addOnce(ytEditProfile);
-
- // Load Web Detective file
- this.webDetective = this.acUtils.useWebDetective("youtube.xml");
- for (var s in gStrings) {
- gStrings[s] = this.webDetective.getString("youtube", s, gStrings[s]);
- }
- this.ytService.domains = gStrings["domains"];
-
- this.urn = this.ytService.id();
-
- var accounts = this.faves_coop.Account.find({serviceId: YOUTUBE_CONTRACTID});
- if (accounts.length) {
- this.USER = accounts[0].accountId;
- for (var i = 0; i < accounts.length; i++) {
- this.updateActions(accounts[i].id());
- }
- }
-
- this._profiler.profileEventEnd(evtID, "");
- }
-
- youtubeService.prototype.getError =
- function youtubeService_getError (aErrorType, aXML, aHTTPErrorCode) {
- var error = Components.classes["@flock.com/error;1"].createInstance(Ci.flockIError);
- if (aErrorType == "HTTP_ERROR") {
- error.errorCode = aHTTPErrorCode;
- } else if (aErrorType == "SERVICE_ERROR") {
- var errorCode;
- var errorMessage;
- var serviceErrorMessage;
- try {
- errorCode = aXML.getElementsByTagName("error")[0].getAttribute('code');
- serviceErrorMessage = aXML.getElementsByTagName("error")[0].getAttribute('description');
- } catch (ex) {
- errorCode = "999" // in case the error xml is invalid
- }
-
- switch (errorCode) { // http://www.youtube.com/dev_error_codes
- case "1":
- error.errorCode = error.HTTP_INTERNAL_SERVER_ERROR;
- break;
-
- case "2": // These errors are due to Flock sending a bad request
- case "3":
- case "4":
- case "5":
- case "6":
- error.errorCode = error.PHOTOSERVICE_INVALID_QUERY;
- break;
-
- case "7":
- case "8":
- error.errorCode = error.PHOTOSERVICE_INVALID_API_KEY;
- break;
-
- case "999":
- error.errorCode = error.PHOTOSERVICE_UNKNOWN_ERROR;
- break;
-
- default:
- error.errorCode = error.PHOTOSERVICE_UNKNOWN_ERROR;
- break;
- }
- }
- error.serviceErrorCode = errorCode;
- error.serviceErrorString = serviceErrorMessage;
- this._logger.error(error.errorString);
- return error;
- };
-
- // BEGIN flockIPhotoAPI interface
- youtubeService.prototype.__defineGetter__('authState', function () { return this.state; })
- youtubeService.prototype.__defineGetter__('firstRunPerson', function () { throw "NotImplemented"; })
- youtubeService.prototype.iconUrl = YOUTUBE_FAVICON;
- youtubeService.prototype.__defineGetter__('isLoggedIn', function () { return this.api.isLoggedIn; })
- youtubeService.prototype.__defineGetter__('isUploading', function () { return this.running; })
- youtubeService.prototype.serviceName = "YouTube";
- youtubeService.prototype.shortName = "youtube";
-
-
- youtubeService.prototype.authenticatedCall = function(aListener, aMethod, aParams) {
- throw "NotImplemented";
- }
-
- var channels = {
- 'special:added': {
- title: 'Recently Added',
- supportsSearch: false,
- feed: 'http://youtube.com/rss/global/recently_added.rss'
- },
- 'special:featured': {
- title: 'Recently Featured',
- supportsSearch: false
- },
- 'special:top_favorites': {
- title: 'Top Favorites',
- supportsSearch: false,
- feed: 'http://youtube.com/rss/global/top_favorites.rss'
- },
- 'special:rated': {
- title: 'Top Rated',
- supportsSearch: false,
- feed: 'http://youtube.com/rss/global/top_rated.rss'
- }
- }
-
- youtubeService.prototype.supportsSearch =
- function youtubeService_supportsSearch( aQueryString ) {
- var aQuery = new queryHelper(aQueryString);
-
- if (aQuery.special) {
- var channel = channels["special:" + aQuery.special];
- if (channel) {
- return channel.supportsSearch;
- }
- }
-
- // none of the other apis/feeds support search
- return false;
- }
-
- youtubeService.prototype.getChannel =
- function youtubeService_getChannel(aChannelId)
- {
- if (!(aChannelId in channels)) return null;
-
- var nc = Components.classes['@flock.com/media-channel;1']
- .createInstance(Components.interfaces.flockIMediaChannel);
- nc.id = aChannelId;
- nc.title = channels[aChannelId].title
- nc.supportsSearch = channels[aChannelId].supportsSearch;
- return nc;
- }
-
- youtubeService.prototype.__defineGetter__('channels', function () {
- var ar = [];
-
- for (var id in channels) {
- var nc = Components.classes['@flock.com/media-channel;1']
- .createInstance(Components.interfaces.flockIMediaChannel);
- nc.id = id;
- nc.title = channels[id].title
- nc.supportsSearch = channels[id].supportsSearch;
- ar.push(nc);
- }
-
- var rval = {
- getNext: function() {
- var rval = ar.shift();
- return rval;
- },
- hasMoreElements: function() {
- return (ar.length > 0);
- }
- }
- return rval;
- })
-
-
- youtubeService.prototype.call =
- function youtubeService_call(aListener, aMethod, aParams)
- {
- var url = "http://www.youtube.com/api2_rest?method=" + aMethod + "&dev_id=" + YT_DEVID;
- for (p in aParams) {
- url += "&" + p + "=" + aParams[p];
- }
- var hr = Components.classes['@mozilla.org/xmlextras/xmlhttprequest;1']
- .createInstance(Components.interfaces.nsIXMLHttpRequest)
- .QueryInterface(Components.interfaces.nsIJSXMLHttpRequest);
-
- var inst = this;
- hr.onreadystatechange = function (aEvt) {
- if (hr.readyState == 4) {
- try {
- if (hr.status/100 == 2) {
- var rsp = hr.responseXML.getElementsByTagName("ut_response")[0];
- var stat = rsp.getAttribute("status");
- if (stat != "ok") {
- var error = inst.getError('SERVICE_ERROR', hr.responseXML, null);
- aListener.onError(error);
- }
- else {
- aListener.onResult(hr.responseXML);
- }
- }
- else {
- // http errors
- aListener.onError(inst.getError("HTTP_ERROR", null, hr.status));
- }
- } catch(e) {
- // XMHTTPERROR (connection lost)
- inst._logger.error(e);
- aListener.onError(inst.getError("HTTP_ERROR", null, "9001"));
- }
- }
- };
-
- hr.detachLoadGroup = true;
- hr.open('GET', url,true);
- hr.send(null);
- }
-
- youtubeService.prototype.getFeed =
- function youtubeService_getFeed(aListener, aFeedURL)
- {
- ios = Components.classes["@mozilla.org/network/io-service;1"]
- .getService(Components.interfaces.nsIIOService);
- var uri = ios.newURI(aFeedURL, null, null);
-
- var ytServ = this;
- var feedListener = {
- onGetFeedComplete: function oncomplete (feed) {
- ytServ.handleFeedResult(aListener, feed);
- },
- onError: aListener.onError
- };
-
- var fm = Components.classes["@flock.com/feed-manager;1"]
- .getService(Components.interfaces.flockIFeedManager);
- fm.getFeed(uri, feedListener);
- }
-
- youtubeService.prototype.createAlbum =
- function youtubeService_createAlbum(aListener, aAlbumName)
- {
- throw "NotImplemented";
- }
-
- youtubeService.prototype.findByUsername =
- function youtubeService_findByUsername(aListener, aUsername)
- {
- var inst = this;
- var myListener = {
- onResult: function (aXML) {
- var newUserObj = Components.classes[FLOCK_PHOTOPERSON_CONTRACTID]
- .createInstance(Components.interfaces.flockIPhotoPerson);
- newUserObj.service = inst;
- newUserObj.id = aUsername;
- newUserObj.username = aUsername;
- newUserObj.fullname = aUsername;
- aListener.onFindByUsernameResult(newUserObj);
- },
- onError: function (aXML) {
- aListener.onError(aXML);
- }
- }
- var params = {};
- params.user = aUsername;
- this.call(myListener, "youtube.users.get_profile", params);
- }
-
- youtubeService.prototype.getAlbums = function(aListener, aUsername) { throw "NotImplemented"; }
- youtubeService.prototype.getAuthPerson = function() {
- if (!this.user) return null;
- var newUserObj = Components.classes[FLOCK_PHOTOPERSON_CONTRACTID]
- .createInstance(Components.interfaces.flockIPhotoPerson);
- newUserObj.id = this.api.user.username
- newUserObj.username = this.api.user.username;
- newUserObj.fullname = this.api.user.username;
- newUserObj.service = this;
- return newUserObj;
- }
- youtubeService.prototype.getContacts = function(aListener) { throw "NotImplemented"; }
- youtubeService.prototype.getMostRecentPhotoForList = function(aListener, aEnumerator) { throw "NotImplemented"; }
- youtubeService.prototype.getPhoto = function(aListener, aPhotoID) { throw "NotImplemented"; }
- youtubeService.prototype.getValidPerson = function(aListener, aURL) { throw "NotImplemented"; }
- youtubeService.prototype.login = function(aAccountURN, aListener) { throw "NotImplemented"; }
-
- youtubeService.prototype.queryChannel =
- function youtubeService_queryChannel(aListener, aQueryString, aCount, aPage)
- {
- var aQuery = new queryHelper(aQueryString);
- // return; // XXX TODO FIXME: This is killing perf
-
- var inst = this;
- var myListener = {
- onResult: function (aXML) {
- var rval = inst.handlePhotosResult(aXML);
- var enum_ = {
- hasMoreElements: function() {
- return (rval.length > 0);
- },
- getNext: function() {
- return rval.shift();
- }
- }
- aListener.onSearchResult(enum_);
- },
- onError: function (aError) {
- aListener.onError(aError);
- }
- }
-
- var params = {}
- if (aQuery.search) {
- params.tag = aQuery.search;
- params.page = aPage;
- params.per_page = aCount;
- this.call(myListener, 'youtube.videos.list_by_tag', params);
- } else {
- // this API call doesn't support pagination and only shows most recent 25 items
- if (aPage > 1) return;
-
- var channel = channels[aQuery.stringVal];
- if (!channel) return;
-
- if (channel.feed)
- this.getFeed(aListener, channel.feed);
- else
- this.call(myListener, "youtube.videos.list_featured", params);
- }
- }
-
- youtubeService.prototype.search =
- function youtubeService_search( aListener, aQueryString, aCount, aPage )
- {
-
- var aQuery = new queryHelper(aQueryString);
- if (aPage > 1) return; // youtube doesn't support pagination
- if(aQuery.favorites && !aQuery.user)
- {
- aQuery.user = aQuery.favorites;
- }
- if (!aQuery.user && aQuery.special != "favorites") {
- this.queryChannel( aListener, aQueryString, aCount, aPage );
- return;
- }
-
-
-
- var aUserid = aQuery.user;
-
- var params = {
- user: aUserid
- };
-
- var inst = this;
- var myListener = {
- onResult: function (aXML) {
- var rval = inst.handlePhotosResult(aXML, aUserid);
- var enum_ = {
- hasMoreElements: function() {
- return (rval.length > 0);
- },
- getNext: function() {
- return rval.shift();
- }
- }
- aListener.onSearchResult(enum_);
- },
- onError: function (aError) {
- aListener.onError(aError);
- }
- }
-
- if (aQuery.favorites) {
- this.call(myListener, "youtube.users.list_favorite_videos", params);
- } else {
- this.call(myListener, "youtube.videos.list_by_user", params);
- }
- }
-
- youtubeService.prototype.getPhotoFromRDFNode =
- function (aRDFId)
- {
- var newPhoto = new youtubeVideo();
- var coopPhoto = this.faves_coop.get(aRDFId);
- newPhoto.webPageUrl = coopPhoto.URL;
- newPhoto.thumbnail = coopPhoto.thumbnail;
- newPhoto.midSizePhoto = coopPhoto.midSizePhoto;
- newPhoto.largeSizePhoto = coopPhoto.largeSizePhoto;
- newPhoto.username = coopPhoto.username;
- newPhoto.userid = coopPhoto.userid;
- newPhoto.title = coopPhoto.name;
- newPhoto.id = coopPhoto.photoid;
- newPhoto.icon = coopPhoto.favicon;
- newPhoto.uploadDate = coopPhoto.datevalue;
- newPhoto.is_public = coopPhoto.is_public;
- newPhoto.is_video = "true";
- return newPhoto;
- // JMC XXX TODO: Gotta add the video-specific fields into the RDF, or somewhere
- // eg content length, rating, etc.
-
- }
-
- youtubeService.prototype.handlePhotosResult =
- function youtubeService_handlePhotoResult(aXML, aUserid)
- {
- var rval = [];
- var photoList = aXML.getElementsByTagName("video");
- for (var i = 0; i < photoList.length; i++) {
- var photo = photoList[i];
- var newPhoto = new youtubeVideo();
- for (var j = 0; j < photo.childNodes.length; j++)
- {
- var child = photo.childNodes[j];
- var contentNode = child.childNodes[0];
- var childContent = "";
- if (contentNode) childContent = contentNode.nodeValue;
- switch (child.tagName)
- {
- case "author":
- newPhoto.username = childContent;
- newPhoto.userid = childContent;
- break;
- // case "id": newPhoto.id = childContent; break;
- case "title": newPhoto.title = childContent; break;
- case "upload_time":
- newPhoto.uploadDate = childContent*1000;
- newPhoto.id = parseInt(childContent);
- break;
- case "length_seconds":
- newPhoto.length_seconds = childContent;
- break
- case "rating_avg":
- newPhoto.rating_avg = childContent;
- break
- case "description":
- newPhoto.description = childContent;
- break
- case "comment_count":
- newPhoto.comment_count = childContent;
- break
- case "view_count":
- newPhoto.view_count = childContent;
- break
- case "rating_count":
- newPhoto.rating_count = childContent;
- break
- case "url":
- newPhoto.webPageUrl = childContent;
- break;
- case "thumbnail_url":
- newPhoto.thumbnail = childContent;
- newPhoto.midSizePhoto = childContent;
- newPhoto.largeSizePhoto = childContent;
- break;
- // case "id": newPhoto.id = childContent;
- // break;
- }
- }
-
- newPhoto.is_public = "true";
- newPhoto.is_video = true;
- rval.push(newPhoto);
- }
- return rval;
- }
-
- youtubeService.prototype.handlePeopleResult =
- function youtubeService_handlePeopleResult(aXML, aUserid)
- {
- var rval = [];
- var friendList = aXML.getElementsByTagName("friend");
- for (var i = 0; i < friendList.length; i++) {
- var person = friendList[i];
- var newPerson = {};
- for (var j = 0; j < person.childNodes.length; j++)
- {
- var child = person.childNodes[j];
- var contentNode = child.childNodes[0];
- var childContent = "";
- if (contentNode) childContent = contentNode.nodeValue;
- switch (child.tagName)
- {
- case "user":
- newPerson.name = childContent;
- newPerson.accountId = childContent;
- break;
- /*
- case "friend_count": newPerson.friend_count = childContent; break;
- case "video_upload_count":
- newPerson.videoCount = childContent;
- break;
- */
- }
- }
- rval.push(newPerson);
- }
- return rval;
- }
-
-
-
- youtubeService.prototype.handleFeedResult =
- function youtubeService_handleFeedResult(aListener, aFeed)
- {
- var photos = [];
-
- var items = aFeed.getItems();
- while (items && items.hasMoreElements()) {
- var item = items.getNext();
-
- var newPhoto = new youtubeVideo();
-
- newPhoto.title = item.getTitle();
- newPhoto.webPageUrl = item.getLink().spec;
-
- newPhoto.uploadDate = item.getPubDate();
- newPhoto.id = newPhoto.uploadDate / 1000;
-
- var author = item.getAuthor();
- newPhoto.username = author;
- newPhoto.userid = author;
-
- var desc = item.getContent();
- var re = /<img [^>]*src="([^"]*)"/i;
- var thumbnail = desc.match(re)[1];
- newPhoto.thumbnail = thumbnail;
- newPhoto.midSizePhoto = thumbnail;
- newPhoto.largeSizePhoto = thumbnail;
-
- newPhoto.is_public = "true";
- newPhoto.is_video = true;
-
- photos.push(newPhoto);
- }
-
- var enum_ = {
- hasMoreElements: function() {
- return (photos.length > 0);
- },
- getNext: function() {
- return photos.shift();
- }
- }
- aListener.onSearchResult(enum_);
- }
-
-
- youtubeService.prototype.supportsFeature = function(aFeature) {
- var supports = {};
- supports.tags = true;
- supports.title = true;
- supports.fileName = false;
- supports.contacts = true;
- supports.privacy = false;
- supports.albumCreation = false;
- return (supports[aFeature] == true);
- }
- youtubeService.prototype.upload = function(aListener, aFile, aParams, aUpload) { throw "NotImplemented"; }
- youtubeService.prototype.upload2 = function(aListener, aUpload, aFilename) { throw "NotImplemented"; }
-
-
-
- function dictionary2Params(aDictionary) {
- var params = {};
- var obj = {};
- var count = {};
- var keys = aDictionary.getKeys(count, obj);
- for (var i = 0; i < keys.length; ++i) {
- var supports = aDictionary.getValue(keys[i]);
- var supportsString = supports.QueryInterface(Components.interfaces.nsISupportsString);
- var val = supportsString.toString();
- params[keys[i]] = val;
- }
- return params;
- }
-
-
- youtubeService.prototype.refresh =
- function youtubeService_refresh(aURN, aListener)
- {
- DEBUG("refresh with aURN of " + aURN);
- var refreshItem = this.faves_coop.get(aURN);
-
- if (refreshItem.isInstanceOf(this.faves_coop.Account)) {
- this.refreshAccount(aURN, aListener);
- } else if (refreshItem.isInstanceOf(this.faves_coop.Favorite)) {
- this.refreshItem(aURN, aListener);
- } else if (refreshItem.isInstanceOf(this.faves_coop.MediaQuery)) {
- // TODO refresh MediaQueries?
- } else {
- throw Components.results.NS_ERROR_ABORT;
- }
- }
-
- youtubeService.prototype.refreshItem =
- function youtubeService_refreshItem(aURN, aListener)
- {
- throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
- }
-
- youtubeService.prototype.refreshAccount =
- function youtubeService_refreshAccount(aURN, aListener)
- {
- if (!aURN) return;
- var refreshItem = this.faves_coop.get(aURN);
- this.getFriends(aListener, refreshItem);
- }
-
- // JMC - Convenience wrapper, probably overkill
- youtubeService.prototype.addFoafPerson =
- function youtubeService_addFoafPerson(aPhotoPerson, aFriendOfURN)
- {
- }
-
- // JMC - XXX TODO - Need to sanity the diff between currAcct and aAccount in all
- // these methods, make sure it makes sense
-
- youtubeService.prototype.addCoopPerson =
- function youtubeService_addCoopPerson(aPhotoPerson, bIsTransient, aFriendOfURN)
- {
- }
-
- youtubeService.prototype.addMediaStream =
- function youtubeService_addMediaStream(aFriend, aCoopAccount)
- {
- var query = new queryHelper();
- query.user = aFriend.accountId;
- query.username = aFriend.accountId;
- var mediaqueryURN = "urn:media:favorites:youtube:"+query.stringVal;
- var mediaquery = this.faves_coop.get(mediaqueryURN);
- if (!mediaquery) {
- mediaquery = new this.faves_coop.MediaQuery(
- mediaqueryURN,
- {
- serviceId: PHOTOAPIMGR_CONTRACTID,
- service: this.shortName,
- favicon: YOUTUBE_FAVICON
- }
- );
- }
- mediaquery.query = query.stringVal;
- mediaquery.name = aFriend.name;
- mediaquery.isPollable = true;
- mediaquery.isTransient = aCoopAccount.isTransient;
- var mediaFavesURN = "urn:media:favorites";
- var mediaFaves = this.faves_coop.get(mediaFavesURN);
- if (!mediaFaves) {
- mediaFaves = new this.faves_coop.Folder(mediaFavesURN);
- this.faves_coop.favorites_root.children.add(mediaFaves);
- }
- mediaFaves.children.addOnce(mediaquery);
- }
-
- youtubeService.prototype.handleFriendsResult =
- function youtubeService_handleFriendsResult(aXML, aAccount)
- {
- DEBUG(".handleFriendsResult(aXML, aAccount)");
- var friendList = aXML.getElementsByTagName("friend");
- DEBUG(" - found "+friendList.length+" friends");
- for (var i = 0; i < friendList.length; i++) {
- var friend = friendList[i];
- var friendObj = {};
- for (var j = 0; j < friend.childNodes.length; j++)
- {
- var child = friend.childNodes[j];
- var contentNode = child.childNodes[0];
- var childContent = "";
- if (contentNode) childContent = contentNode.nodeValue;
- switch (child.tagName)
- {
- case "user":
- {
- friendObj.accountId = childContent;
- friendObj.name = childContent;
- }; break;
- }
- }
- //this.addCoopPerson(friendObj);
- this.addMediaStream(friendObj, aAccount);
- }
- }
-
-
- youtubeService.prototype.getFriends =
- function youtubeService_getFriends(aListener, aAccount)
- {
- var inst = this;
- var myListener = {
- onResult: function (aXML) {
- inst.handleFriendsResult(aXML, aAccount);
- aListener.onResult();
- },
- onError: function (aXML) {
- aListener.onError();
- }
- }
- var params = {};
- params.user = aAccount.accountId;
- this.call(myListener, "youtube.users.list_friends", params);
- }
-
- var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
- .getService(Components.interfaces.mozIJSSubScriptLoader);
- loader.loadSubScript("chrome://browser/content/utilityOverlay.js");
-
-
- youtubeService.prototype.doAction =
- function youtubeService_doAction(aMethodName, aURN, aSubject)
- {
-
- var actionTarget = this.faves_coop.get(aURN);
- switch (aMethodName)
- {
- case "openProfile":
- return gStrings["userprofile"].replace("%accountid%", actionTarget.accountId);
- break;
- case "openSubscriptions":
- return gStrings["subscriptions"];
- break;
- case "openVideos":
- // return "http://youtube.com/my_videos";
- var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
- var win = wm.getMostRecentWindow('navigator:browser');
- if (win) {
- win.gPhotoDrawer.loadPhotoPerson(aURN, this.shortName);
- }
- break;
- case "openFavVideos":
- // return "http://youtube.com/my_favorites";
- var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
- var win = wm.getMostRecentWindow('navigator:browser');
- if (win) {
- win.gPhotoDrawer.loadQuery(this.shortName, "favorites:" + actionTarget.accountId, actionTarget.name);
- }
- break;
- case "openInbox":
- return gStrings["inbox"];
- break;
- case "editProfile":
- return gStrings["editprofile"];
- break;
- case "postComment":
- return actionTarget.URL + "?mode=reply";
- break;
- case "viewFriends":
- // Dangerous assumption that the people sidebar is open when this is called
- var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
- var win = wm.getMostRecentWindow('navigator:browser');
- if (win) {
- var peepsSidebar = win.document.getElementById('sidebar').contentWindow;
- if (peepsSidebar)
- peepsSidebar.gPeopleBrowser.getCurrent(actionTarget.id());
- }
- break;
- default:
- dump("BORK BORK - undefined action in youtube\n");
- break;
- }
- return null;
- }
-
- youtubeService.prototype.updateActions =
- function youtubeService_updateActions(aURN)
- {
- var coopObj = this.faves_coop.get(aURN);
- if (coopObj.isInstanceOf(this.faves_coop.Account)) {
- coopObj.enabledAction.removeAll();
- var serviceActions = this.ytService.children.enumerate();
- while (serviceActions.hasMoreElements()) {
- var action = serviceActions.getNext();
- if (action.flavour == "accountaction" ||
- action.flavour == "accountview" ||
- action.flavour == "view")
- {
- coopObj.enabledAction.add(action);
- }
- }
- }
- }
-
-
- // BEGIN flockIWebService inteface
- youtubeService.prototype.addAccountById =
- function youtubeService_addAccountById(aAccountID, aIsTransient, aListener)
- {
- DEBUG("{flockIWebService}.addAccountById('"+aAccountID+"', "+aIsTransient+", aListener)");
-
- var accountURN = "urn:flock:youtube:"+aAccountID;
- var account = new this.faves_coop.Account(
- accountURN,
- {
- name: aAccountID,
- serviceId: YOUTUBE_CONTRACTID,
- service: this.ytService,
- accountId: aAccountID,
- URL: gStrings["userprofile"].replace("%accountid%", aAccountID),
- isTransient: aIsTransient,
- favicon: YOUTUBE_FAVICON
- }
- );
- this.account_root.children.add(account);
- this.USER = account.id();
- var notifUrn = accountURN + ":notifications";
- var notifications = new this.faves_coop.Stream(
- notifUrn,
- {
- name: "YouTube Notifications",
- isPollable: false,
- isIndexable: false,
- notify: true,
- serviceId: YOUTUBE_CONTRACTID
- }
- );
- account.children.addOnce(notifications);
-
- // Instanciate account component
- var acct = this.getAccount(account.id());
- if (aListener) aListener.onSuccess(acct, "addAccount");
- return acct;
- }
- // END flockIWebService interface
-
-
- // BEGIN flockIManageableWebService interface
- youtubeService.prototype.updateAccountStatusFromDocument =
- function youtubeService_updateAccountStatusFromDocument(aDocument)
- {
- DEBUG("{flockIManageableWebService}.updateAccountStatusFromDocument(aDocument)");
- if (this.docRepresentsSuccessfulLogin(aDocument)) {
- var accountID = this.getAccountIDFromDocument(aDocument);
- var acctURN = this.acUtils.getAccountURNById(this.urn, accountID);
- var accounts = this.faves_coop.Account.find({serviceId: YOUTUBE_CONTRACTID});
- for (var i = 0; i < accounts.length; i++) {
- if (accounts[i].id() == acctURN) {
- accounts[i].isAuthenticated = true;
- this.USER = acctURN;
- } else {
- accounts[i].isAuthenticated = false;
- }
- }
- } else {
- this.acUtils.markAllAccountsAsLoggedOut(YOUTUBE_CONTRACTID);
- }
- }
- // END flockIManageableWebService interface
-
-
- // BEGIN flockISocialWebService interface
- youtubeService.prototype.decorateForPerson =
- function youtubeService_decorateForPerson(aDocument)
- {
- DEBUG("{flockISocialWebService}.decorateForPerson()");
- }
-
- youtubeService.prototype.browseFriends =
- function youtubeService_browseFriends(aFriendURN, aListener)
- {
- DEBUG("{flockISocialWebService}.browseFriends('"+aFriendURN+"')");
- }
- // END flockISocialWebService interface
-
-
- youtubeService.prototype.getFriendsContacts =
- function youtubeService_getFriendsContacts(aListener, aUsername)
- {
- var inst = this;
- var myListener = {
- onResult: function (aXML) {
- var rval = inst.handlePeopleResult(aXML);
- var enum_ = {
- hasMoreElements: function() {
- return (rval.length > 0);
- },
- getNext: function() {
- return rval.shift();
- }
- }
- aListener.onGetContactsResult(enum_);
- },
- onError: function (aXML) {
- aListener.onError(aXML);
- }
- }
- var params = {};
- params.user = aUsername;
- this.call(myListener, "youtube.users.list_friends", params);
- }
-
-
- // BEGIN flockIMediaWebService interface
- youtubeService.prototype.decorateForMedia =
- function youtubeService_decorateForMedia(aDocument)
- {
- DEBUG("{flockIMediaWebService}.decorateForMedia(aDocument)");
- aDocument.QueryInterface(Components.interfaces.nsIDOMHTMLDocument);
- var results = Components.classes["@mozilla.org/hash-property-bag;1"]
- .createInstance(Components.interfaces.nsIWritablePropertyBag2);
- if (this.webDetective.detect("youtube", "media", aDocument, results)) {
- var mediaArr = [];
-
- // media item for user videos
- var userid = results.getPropertyAsAString("userid");
- var media = {
- name: userid,
- query: 'user:' + userid + "|username:" + userid,
- label: userid + "'s Videos", // FIXME: breaks internationalization
- favicon: this.icon,
- service: this.shortName
- }
- mediaArr.push(media);
-
- // media item for user favorites
- var media = {
- name: userid,
- query: 'favorites:' + userid,
- label: userid + "'s Favorites", // FIXME: breaks internationalization
- favicon: this.icon,
- service: this.shortName
- }
- mediaArr.push(media);
-
- if (!aDocument._flock_decorations) {
- aDocument._flock_decorations = {};
- }
- aDocument._flock_decorations.mediaArr = mediaArr;
- this.obs.notifyObservers(aDocument, 'media', 'media:update');
- }
- }
-
- youtubeService.prototype.handlesMediaStream =
- function youtubeService_handlesMediaStream()
- {
- return true;
- }
-
- youtubeService.prototype.checkIsStreamUrl =
- function youtubeService_checkIsStreamUrl(aUrl)
- {
- this._logger.debug("Checking Stream Url for Youtube: " + aUrl);
- if (aUrl.match(/^https?:\/\/[^\/]*\.?youtube.com\/v\/.*/) ||
- aUrl.match(/^https?:\/\/[^\/]*\.?youtube.com\/watch\/v\/.*/) ||
- aUrl.match(/^https?:\/\/[^\/]*\.?youtube.com\/watch\?v=.*/) ||
- aUrl.match(/^\/player\w*\.swf\?v*/) ) {
- return true;
- }
-
- return false;
- }
-
- youtubeService.prototype.getVideoIDFromUrl =
- function youTubeService_getVideoIDFromUrl(aUrl)
- {
- // These are image link matches
- //http://www.youtube.com/v/lp_daXRkOH0
- userMatch = aUrl.match(/^https?:\/\/[^\/]*\.?youtube.com\/v\/(.*)/);
- if (userMatch) {
- return userMatch[1];
- }
- //http://www.youtube.com/watch/v/YP2rgi978tw
- userMatch = aUrl.match(/^https?:\/\/[^\/]*\.?youtube.com\/watch\/v\/(.*)/);
- if (userMatch) {
- return userMatch[1];
- }
- //http://www.youtube.com/watch?v=BjfbS_Kj-J0
- userMatch = aUrl.match(/^https?:\/\/[^\/]*\.?youtube.com\/watch\?v=(.*)/);
- if (userMatch) {
- return userMatch[1];
- }
-
- // These are flash video sources matching
- // /player2.swf?video_id=xPxDw7ajfGE&....
- var userMatch = aUrl.match(/^\/player2\.swf\?.*video_id=([^&]+).*/);
- if (userMatch){
- return userMatch[1];
- }
-
- return null;
- }
-
- youtubeService.prototype.getMediaQueryFromURL =
- function youTubeService_getMediaQueryFromURL(aUrl, aListener)
- {
- var videoId = this.getVideoIDFromUrl(aUrl);
- if (videoId) {
- var myListener = {
- onResult: function (aXML) {
- var userID = aXML.getElementsByTagName('author')[0].firstChild.nodeValue;
- var results = Components.classes["@mozilla.org/hash-property-bag;1"]
- .createInstance(Components.interfaces.nsIWritablePropertyBag2);
- results.setPropertyAsAString("query", "user:" + userID + "|username:" + userID);
- results.setPropertyAsAString("title", this.title + " user: " + userID);
- aListener.onSuccess(results, "query");
- },
- onError: function (aError) {
- aListener.onError(null, aError, null);
- }
- }
- var params = {};
- params.video_id = videoId;
- this.call(myListener, "youtube.videos.get_details", params);
- } else {
- aListener.onError(null, "Unable to get user.", null);
- }
- }
-
- // END flockIMediaWebService interface
-
-
- // ========== END youtubeService class ==========
-
-
-
- // ================================================
- // ========== BEGIN youtubeAccount class ==========
- // ================================================
-
- function youtubeAccount()
- {
- this.acUtils = Components.classes["@flock.com/account-utils;1"]
- .getService(Components.interfaces.flockIAccountUtils);
- this.service = Components.classes[YOUTUBE_CONTRACTID]
- .getService(Components.interfaces.flockIWebService)
- .QueryInterface(Components.interfaces.flockISocialWebService);
- this._coop = Components.classes["@flock.com/singleton;1"]
- .getService(Components.interfaces.flockISingleton)
- .getSingleton("chrome://browser/content/flock/common/load-faves-coop.js")
- .wrappedJSObject;
- this._ctk = {
- interfaces: [
- "nsISupports",
- "flockIWebServiceAccount",
- "flockIMediaWebServiceAccount",
- "flockISocialWebServiceAccount",
- ]
- };
- getCompTK().addAllInterfaces(this);
- }
-
-
- // BEGIN flockIWebServiceAccount interface
- youtubeAccount.prototype.urn = "";
- youtubeAccount.prototype.username = "";
- youtubeAccount.prototype.status = "";
-
- youtubeAccount.prototype.activate =
- function youtubeAccount_activate(aListener)
- {
- DEBUG("{flockIWebServiceAccount}.activate()");
- var acctCoopObj = this._coop.get(this.urn);
- acctCoopObj.isPollable = true;
- if (aListener) {
- aListener.onSuccess(this, "accountAuthorized");
- }
- }
-
- youtubeAccount.prototype.login =
- function youtubeAccount_login(aListener)
- {
- DEBUG("{flockIWebServiceAccount}.login()");
- }
- // END flockIWebServiceAccount interface
-
-
- // BEGIN flockISocialWebServiceAccount interface
- youtubeAccount.prototype.browseFriends =
- function youtubeAccount_browseFriends(aFriendURN, aListener)
- {
- DEBUG("{flockISocialWebServiceAccount}.browseFriends('"+aFriendURN+"')");
- this.service.browseFriends(aFriendURN, aListener);
- }
- // END flockISocialWebServiceAccount interface
-
- // ========== END youtubeAccount class ==========
-
-
-
- // ==============================================
- // ========== BEGIN XPCOM registration ==========
- // ==============================================
-
- function createModule(aParams) {
- return {
- registerSelf: function (aCompMgr, aFileSpec, aLocation, aType) {
- aCompMgr.QueryInterface(Ci.nsIComponentRegistrar);
- aCompMgr.registerFactoryLocation( aParams.CID, aParams.componentName,
- aParams.contractID, aFileSpec,
- aLocation, aType );
- var catMgr = Cc["@mozilla.org/categorymanager;1"]
- .getService(Ci.nsICategoryManager);
- if (!aParams.categories) { aParams.categories = []; }
- for (var i = 0; i < aParams.categories.length; i++) {
- var cat = aParams.categories[i];
- catMgr.addCategoryEntry( cat.category, cat.entry,
- cat.value, true, true );
- }
- },
- getClassObject: function (aCompMgr, aCID, aIID) {
- if (!aCID.equals(aParams.CID)) { throw Cr.NS_ERROR_NO_INTERFACE; }
- if (!aIID.equals(Ci.nsIFactory)) { throw Cr.NS_ERROR_NOT_IMPLEMENTED; }
- return { // Factory
- createInstance: function (aOuter, aIID) {
- if (aOuter != null) { throw Cr.NS_ERROR_NO_AGGREGATION; }
- var comp = new aParams.componentClass();
- if (aParams.implementationFunc) { aParams.implementationFunc(comp); }
- return comp.QueryInterface(aIID);
- }
- };
- },
- canUnload: function (aCompMgr) { return true; }
- };
- }
-
- // NS Module entrypoint
- function NSGetModule(aCompMgr, aFileSpec) {
- return createModule({
- componentClass: youtubeService,
- CID: YOUTUBE_CID,
- contractID: YOUTUBE_CONTRACTID,
- componentName: CATEGORY_COMPONENT_NAME,
- implementationFunc: function (aComp) { getCompTK().addAllInterfaces(aComp); },
- categories: [
- { category: "wsm-startup", entry: CATEGORY_COMPONENT_NAME, value: YOUTUBE_CONTRACTID },
- { category: "flockIPhotoAPI", entry: CATEGORY_ENTRY_NAME, value: YOUTUBE_CONTRACTID },
- { category: "flockWebService", entry: CATEGORY_ENTRY_NAME, value: YOUTUBE_CONTRACTID }
- ]
- });
- }
-
- // ========== END XPCOM registration ==========
-
-
-
- // HELPER STUFF
-
- function loadSubScript(spec)
- {
- var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
- .getService(Components.interfaces.mozIJSSubScriptLoader);
- var context = {};
- loader.loadSubScript(spec, context);
- return context;
- }
-
- function loadLibraryFromSpec(aSpec)
- {
- var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
- .getService(Components.interfaces.mozIJSSubScriptLoader);
- loader.loadSubScript(aSpec);
- }
-